/**
 * @file    bl24xx_driver.c
 * @brief   EEPROM驱动 -BL24X系列
 * @author  Liuwei
 * @version 1.0.1
 * @date    2023-04-22
 * 
 * @copyright Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version   <th>Author   <th>Description
 * <tr><td>2023-04-22 <td>1.0.1     <td>Liuwei   <td>首次创建
 * </table>
 */

/* includes ------------------------------------------------------------------*/
#include "drv_i2c_soft.h"
#include "dev_eep_24cxx.h"
/* macro/define --------------------------------------------------------------*/

/* typedef -------------------------------------------------------------------*/

/* local functions -----------------------------------------------------------*/

/* static variables ----------------------------------------------------------*/

/* global variables ----------------------------------------------------------*/

/** ------------------------------------------------------------------------- *
  *                             Global function
 ** ------------------------------------------------------------------------- */
/**
 * @brief  检测EEPROM是否在线
 * @return TRUE : 在线  FALSE : 不在线 
 */
uint8_t dev_eep_check_online(void) 
{
    return drv_i2c_soft_check_device(EEP_DRV_I2C , EEP_DEV_ADDR);
}

/**
 * @brief  连续读取EEPROM 多个字节
 * @param  eep_addr : 读取地址
 * @param  read_buf : 读取缓冲区
 * @param  read_size : 读取大小
 * @return uint8_t 读取结果
 *         TRUE : 读取成功
 *         FALSE: 读取失败
 */
uint8_t dev_eep_read_bytes(uint32_t eep_addr, uint8_t *rd_buf, uint32_t read_size)
{
    uint16_t i;

    drv_i2c_soft_start(EEP_DRV_I2C);

#if EEP_ADDR_A8 == 1
    drv_i2c_soft_write_byte(EEP_DRV_I2C , EEP_DEV_ADDR | DEV_I2C_WR | ((eep_addr >> 7) & 0x0E)); 
#else
    drv_i2c_soft_write_byte(EEP_DRV_I2C , EEP_DEV_ADDR | DEV_I2C_WR); 
#endif

    if (FALSE == drv_i2c_soft_read_ack(EEP_DRV_I2C)) 
    {
		drv_i2c_soft_stop(EEP_DRV_I2C); 
		return 0;
	}

    if (1 == EEP_ADDR_BYTES) 
    {
        drv_i2c_soft_write_byte(EEP_DRV_I2C , (uint8_t) eep_addr);
        if (FALSE == drv_i2c_soft_read_ack(EEP_DRV_I2C)) 
        { 
			drv_i2c_soft_stop(EEP_DRV_I2C);
			return 0;
		}
    } 
    else 
    {
        drv_i2c_soft_write_byte(EEP_DRV_I2C ,(uint8_t)((eep_addr >> 8) & 0xff));
        if (FALSE == drv_i2c_soft_read_ack(EEP_DRV_I2C)) 
        { 
			drv_i2c_soft_stop(EEP_DRV_I2C);
			return 0;
		}
        drv_i2c_soft_write_byte(EEP_DRV_I2C ,(uint8_t)(eep_addr & 0xff));
        if (FALSE == drv_i2c_soft_read_ack(EEP_DRV_I2C)) 
        { 
			drv_i2c_soft_stop(EEP_DRV_I2C);
			return 0;
		}
    }

    drv_i2c_soft_start(EEP_DRV_I2C);

#if EE_ADDR_A8 == 1
    drv_i2c_soft_write_byte(EEP_DRV_I2C , EE_DEV_ADDR | DEV_I2C_RD | ((eep_addr >> 7) & 0x0E)); /* 此处是写指令 */
#else
    drv_i2c_soft_write_byte(EEP_DRV_I2C , EEP_DEV_ADDR | DEV_I2C_RD); /* 此处是写指令 */
#endif

    if (FALSE == drv_i2c_soft_read_ack(EEP_DRV_I2C)) 
    { 
		drv_i2c_soft_stop(EEP_DRV_I2C);
		return FALSE;
	}

    for (i = 0; i < read_size; i++) 
    {
        rd_buf[i] = drv_i2c_soft_read_byte(EEP_DRV_I2C); 
        if (i < (read_size - 1))
        {
            drv_i2c_soft_write_ack(EEP_DRV_I2C); 
        } 
        else 
        {
            drv_i2c_soft_write_nack(EEP_DRV_I2C); 
        }
    }

    drv_i2c_soft_stop(EEP_DRV_I2C);
	
    return TRUE; 
}

/**
 * @brief  连续写多个字节数据
 * @param  eep_addr : EEPROM 地址
 * @param  write_buf : 写缓冲区
 * @param  size : 缓冲区大小
 * @return uint8_t : 写入结果
 *         TRUE : 写入成功
 *         FALSE : 写入失败
 */
uint8_t dev_eep_write_bytes(uint32_t eep_addr, uint8_t *wr_buf, uint32_t size) 
{
    uint16_t i = 0;
    uint16_t m = 0;
	uint32_t addr_cnt = 0;

	addr_cnt = eep_addr;
    for (i = 0; i < size; i++) 
    {
        if ((i == 0) || (addr_cnt & (EEP_PAGE_SIZE - 1)) == 0) 
        {
            drv_i2c_soft_stop(EEP_DRV_I2C);

            eep_delay_ms(3);
            for (m = 0; m < 1000; m++) 
            {
                drv_i2c_soft_start(EEP_DRV_I2C);
#if EE_ADDR_A8 == 1
                drv_i2c_soft_write_byte(EEP_DEV_ADDR | DEV_I2C_WR | ((_usAddress >> 7) & 0x0E)); /* 此处是写指令 */
#else
                drv_i2c_soft_write_byte(EEP_DRV_I2C , EEP_DEV_ADDR | DEV_I2C_WR);
#endif

                if (TRUE == drv_i2c_soft_read_ack(EEP_DRV_I2C)) 
                { 
                    break; 
                }
            }

            if (m == 1000) 
			{ 
				drv_i2c_soft_stop(EEP_DRV_I2C);
				return FALSE;
			}

            if (EEP_ADDR_BYTES == 1) {
                drv_i2c_soft_write_byte(EEP_DRV_I2C , (uint8_t) addr_cnt);
                if (drv_i2c_soft_read_ack(EEP_DRV_I2C) != 0) 
                { 
					drv_i2c_soft_stop(EEP_DRV_I2C);
					return FALSE;
				}
            } 
            else 
            {
                drv_i2c_soft_write_byte(EEP_DRV_I2C , (uint8_t)(addr_cnt >> 8));
                if (FALSE == drv_i2c_soft_read_ack(EEP_DRV_I2C)) 
                { 
					drv_i2c_soft_stop(EEP_DRV_I2C);
					return FALSE;
				}
                drv_i2c_soft_write_byte(EEP_DRV_I2C , (uint8_t)(addr_cnt));
                if (FALSE == drv_i2c_soft_read_ack(EEP_DRV_I2C)) 
                { 
					drv_i2c_soft_stop(EEP_DRV_I2C);
					return FALSE;
				}
            }
        }

        drv_i2c_soft_write_byte(EEP_DRV_I2C , wr_buf[i]);

        if (FALSE == drv_i2c_soft_read_ack(EEP_DRV_I2C)) 
        { 
			drv_i2c_soft_stop(EEP_DRV_I2C);
			return FALSE;
		}

        ++ addr_cnt; 
    }

    drv_i2c_soft_stop(EEP_DRV_I2C);
    for (m = 0; m < 1000; m++) 
    {
        drv_i2c_soft_start(EEP_DRV_I2C);
#if EE_ADDR_A8 == 1
        drv_i2c_soft_write_byte(EEP_DEV_ADDR | DEV_I2C_WR | ((eep_addr >> 7) & 0x0E)); 
#else
        drv_i2c_soft_write_byte(EEP_DRV_I2C , EEP_DEV_ADDR | DEV_I2C_WR); 
#endif
        if (TRUE == drv_i2c_soft_read_ack(EEP_DRV_I2C)) 
        { 
			break; 
		}
    }
    if (m == 1000) 
    { 
		drv_i2c_soft_stop(EEP_DRV_I2C);
		return 0;
	}

    drv_i2c_soft_stop(EEP_DRV_I2C);
	
	eep_delay_ms(5);

    return 1;
}

/**
 * @brief  读取设备容量
 * @return uint32_t : 设备容量值 Byte
 */
uint32_t dev_eep_get_capacity(void) 
{ 
    return EEP_CAPACITY; 
}

/**
 * @brief 设备驱动测试
 */
#define EEP_TEST_SIZE (128)
uint8_t wr_buff[EEP_TEST_SIZE] ; 
uint8_t rd_buff[EEP_TEST_SIZE] ; 
uint32_t wr_times = 0;
uint32_t succ_times = 0;
uint32_t err_times = 0;
uint32_t dev_capacity = 0;

void eep_24xx_drv_test(void)
{
	uint32_t wr_addr = 0;
	uint32_t i = 0;
	
	while(1)
	{
		for( i = 0;i < EEP_TEST_SIZE; ++ i)
		{
			wr_buff[i] = i;
		}
		
		wr_addr += EEP_TEST_SIZE;
		
		++ wr_times;

		dev_eep_write_bytes(wr_addr , wr_buff , EEP_TEST_SIZE);
		
		dev_eep_read_bytes(wr_addr , rd_buff , EEP_TEST_SIZE);
		
		for( i = 0;i < EEP_TEST_SIZE; ++ i)
		{
			if(wr_buff[i] != rd_buff[i])
			{
                err_times ++ ;
				break;
			}
		}

		if(i == EEP_TEST_SIZE)
		{
			++ succ_times;
		}

		eep_delay_ms(1000);
	}
}

/********** Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD *********/
